
#include <stdio.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <iostream>
#include <unistd.h>
#include <fcntl.h>
#include "common.h"
#include "mmap_file.h"
#include "file_op.h"
#include "mmap_file_op.h"
#include "index_handle.h"

using namespace tfs;
using namespace largefile;

const static mode_t fileMode = 0644;

const static uint32_t main_bloc_size = 1024*1024*64;  
const static uint32_t bucket_size = 1000;

static uint32_t block_id = 1;

static struct MMapOption mmap_option = { 1024000 , 4096 ,4096 } ; // 


int  open_file( std::string &fileName , int open_flags ){
    return open( fileName.c_str() ,open_flags , fileMode);
}

#if 0

int main(int, char**){
    /*  1.  文件映射类测试
    std::string fileName = "CodeTest.txt";
    int fd = open_file(fileName , O_RDWR | O_CREAT | O_LARGEFILE );
    if( fd <0 ){
        std::cout<<"file open failed\n";
        return 1;
    }
    std::cout<<"open file successed. "<<"  fd :"<< fd<<std::endl;

    MMapFile mfile( fd , mmap_option );

    if ( !mfile.mmap_file(true) ){
        std::cerr<<"mmap_file is failed!"<<std::endl;
        close(fd);
        return 2;
    }
    mfile.remap_file();

    close(fd);
    */

    /*  2. 文件操作类测试
    const char *fileName ="CodeTest.txt";
    FileOperation *fileOP  = new FileOperation( fileName );

    if ( fileOP->open_file() < 0 ){
        std::cerr<<" open file error"<<std::endl;
        return -errno;
    }

    std::cout<<"open file success!"<<"  fileName: "<< fileName <<" fd:"<<fileOP->get_fd()<<std::endl;

    char buf[64];

    memset( buf ,'6' , 64);

    int ret = fileOP->pwrite_file( buf , 64 , 64 );
    if( ret< 0 ){
        std::cerr<<"pwrite_file error. desc"<< ret <<std::endl;
        return -errno;
    }
    std::cout<<"pwrite_file success!"<<" write buf: "<< buf << std::endl;

    char read_buf[ 128 ] = { 0 };
    ret = fileOP->pread_file( read_buf , 64  , 64 );
    
    if( ret< 0 ){
        std::cerr<<"pread_file error. desc"<< ret <<std::endl;
        return -errno;
    }
    std::cout<<"pread_file success!"<<" read  buf:"<<read_buf<<std::endl;
    
    memset( buf ,'9' ,64);
    fileOP->write_file( buf ,64);

    memset( read_buf , 0  ,128 );

    ret = fileOP->pread_file( read_buf ,128 , 0);
    if( ret< 0 ){
        std::cerr<<"pread_file error. desc"<< ret <<std::endl;
        return -errno;
    }
    
    std::cout<<"pread_file success!"<<" read  buf:"<<read_buf[124]<<std::endl;
    

    

    std::cout<<"file  size: "<<fileOP->get_file_size()<<std::endl;

    fileOP->ftruncate_file( 64 );

    fileOP->close_file();

    fileOP->unlink_file();
    */
    
    /*
       3. 文件映射操作类测试
    const char *fileName ="CodeTest";
    
    MMapFileOperation *mmp_fileOP = new MMapFileOperation( fileName );

    if( mmp_fileOP->open_file() < 0 ){
        std::cerr<<" test 3 open file error "<<std::endl;
        return -errno;
    }

    if( mmp_fileOP->mmap_file( mmap_option ) < 0 ){
        std::cerr<<"test 3 mmap_file  error"<<std::endl;
        return -errno;
    }

    std::cout<<"mmap file successed."<<std::endl;

    // 写数据
    char buf[64] ={ 0 };
    memset( buf ,'6' ,sizeof( buf) );
    if( mmp_fileOP->pwrite_file( buf , sizeof(buf) , 4096 ) < 0 ){
        std::cerr<<"test 3  pwrite_file error"<<std::endl;
        return -errno;
    }

    if( mmp_fileOP->flush_file() < 0 ){
        std::cerr<<"test 3 flush_file error"<<std::endl;
        return -errno;
    }

    std::cout<<"flush_file successed"<<std::endl;

    std::cout<<"write buf"<<buf<<std::endl;
    // 读数据
    char read_buf[64] = { 0 };
    if( mmp_fileOP->pread_file( read_buf ,sizeof(read_buf) ,4096 ) ==0 ){
        std::cout<<"raed buf"<<read_buf<<std::endl;   
    }

    if( mmp_fileOP->munmap_file() < 0 ){
        std::cerr<<"test 3 munmap_file error"<<std::endl;
        return -errno;
    }

    delete mmp_fileOP;
    */

   /*
     4 . 索引文件映射类  test 4 
   */

    std::string mainblock_path;
    std::string index_path;
    int32_t  ret = TSF_SUCCESS;

    std::cout<<"pleas input blockid"<<std::endl;
    std::cin>>block_id;

    if( block_id <0 ){
        std::cout<<"input error"<<std::endl;
        return -1;
    }
    // 1. 生产主块文件
    std::stringstream tmp_stream;
    tmp_stream <<MAINBLOCK_DIR_PREFIX<<block_id;
    tmp_stream >> mainblock_path;

    FileOperation *fileOP = new FileOperation( mainblock_path ,O_CREAT |O_RDWR | O_LARGEFILE ) ;

    // 修改文件大小
    ret = fileOP->ftruncate_file( main_bloc_size );
    if( ret != 0 ){
        std::cerr<<"create main block failed."
                 <<" block id:"<< block_id
                 <<" main block path:"<<mainblock_path<<std::endl;
        delete fileOP;
        return ret;
    }
    // 2. 创建索引文件
    IndexHandle *index_handle = new IndexHandle("." , block_id );

    std::cout<<"init index file.."<<std::endl;
    
    ret = index_handle->create( block_id ,bucket_size , mmap_option );
    if( ret != TSF_SUCCESS ){
        std::cerr<<"index create failed."
                 <<" block_id:"<<block_id
                 <<" bucket_size:"<<bucket_size<<std::endl;
        index_handle->remove( block_id );
        delete index_handle;
        delete fileOP;
        exit( -3 );
    }

    fileOP->close_file();
    index_handle->flush();

    delete index_handle;
    delete fileOP;
    /*
    ret = index_handle->load( block_id , bucket_size ,mmap_option );
    if( ret != TSF_SUCCESS ){
        std::cerr<<" index file load error. desc :"<<strerror( errno )<<std::endl;
        exit( -4);
    }
    */
    return 0;
}

#endif